package com.zmc.admin.controller.system;

import com.zmc.admin.infrastructure.bean.vo.menu.SysMenuVo;
import com.zmc.admin.infrastructure.bean.vo.user.SysRoleVo;
import com.zmc.admin.infrastructure.constant.ErrorCodeConstants;
import com.zmc.admin.infrastructure.constant.UserConstants;
import com.zmc.admin.infrastructure.entity.SysMenuEntity;
import com.zmc.admin.infrastructure.entity.SysUserEntity;
import com.zmc.admin.infrastructure.bean.query.SysMenuQuery;
import com.zmc.admin.infrastructure.service.SysMenuService;
import com.zmc.admin.infrastructure.service.SysUserService;
import com.zmc.common.annotation.PreventRepeatSubmit;
import com.zmc.common.enums.RequestSourceEnum;
import com.zmc.common.exception.base.WebDisplayException;
import com.zmc.common.utils.R;
import com.zmc.common.utils.StringUtils;
import com.zmc.common.utils.token.AuthTokenService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

/**
 * 菜单信息
 * @author zmc
 */
@RestController
@RequestMapping("/menu")
public class SysMenuController {
    @Autowired
    private SysMenuService menuService;

    @Autowired
    private AuthTokenService authTokenService;

    @Autowired
    private SysUserService userService;

    /**
     * 获取菜单列表
     */

    @PostMapping("/list")
    public R list(@RequestBody SysMenuQuery query) {
        SysUserEntity user = userService.getById(authTokenService.getUserInfo().getUserId());
        List<SysMenuEntity> menus = menuService.selectMenuList(query, user);
        return R.ok(menus);
    }

    /**
     * 根据菜单编号获取详细信息
     */
    @PostMapping(value = "info")
    public R getInfo(@RequestBody SysMenuVo vo) {
        return R.ok(menuService.getById(vo.getMenuId()));
    }

    /**
     * 获取菜单下拉树列表
     */
    @PostMapping("/treeselect")
    public R treeSelect() {
        SysUserEntity user = userService.getById(authTokenService.getUserInfo().getUserId());
        List<SysMenuEntity> menus = menuService.selectMenuList(new SysMenuQuery(), user);
        return R.ok(menuService.buildMenuTreeSelect(menus));
    }

    /**
     * 加载对应角色菜单列表树
     */
    @PostMapping(value = "/roleMenuTreeselect")
    public R roleMenuTreeSelect(@RequestBody SysRoleVo vo) {
        SysUserEntity user = userService.getById(authTokenService.getUserInfo().getUserId());
        List<SysMenuEntity> menus = menuService.selectMenuList(new SysMenuQuery(), user);
        return Objects.requireNonNull(R.ok().put("checkedKeys", menuService.selectMenuListByRoleId(vo.getRoleId()))).put("menus", menuService.buildMenuTreeSelect(menus));
    }

    /**
     * 新增菜单
     */
    @PostMapping("/add")
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public R add(@RequestBody SysMenuEntity menu) {
        if (!menuService.checkMenuNameUnique(menu)) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_EXIT_EXCEPTION);
        }
        if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_URL_EXCEPTION);
        }
        menu.setCreateBy(authTokenService.getUserInfo().getUsername());
        menuService.save(menu);
        return R.ok();
    }

    /**
     * 修改菜单
     */
    @PostMapping("/update")
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public R edit(@Validated @RequestBody SysMenuEntity menu) {
        if (!menuService.checkMenuNameUnique(menu)) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_EXIT_EXCEPTION);
        }
        if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_URL_EXCEPTION);
        }
        if (menu.getMenuId().equals(menu.getParentId())) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_PARENT_OWNER_EXCEPTION);
        }
        menu.setUpdateBy(authTokenService.getUserInfo().getUsername());
        menuService.updateById(menu);
        return R.ok();
    }

    /**
     * 删除菜单
     */
    @PostMapping("/delete")
    @PreventRepeatSubmit(lockByPerson = true, source = RequestSourceEnum.MANAGE)
    public R remove(@RequestBody SysMenuVo vo) {
        Long menuId = vo.getMenuId();
        if (menuService.hasChildByMenuId(menuId)) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_HAS_CHILD_EXCEPTION);
        }
        if (menuService.checkMenuExistRole(menuId)) {
            throw new WebDisplayException(ErrorCodeConstants.MENU_HAS_USED_EXCEPTION);
        }
        menuService.removeById(menuId);
        return R.ok();
    }
}